/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define ZlangCreateDirectProperty_(_basetype_) \
ZlangInvokeFunction ZlangInvokeFunction_##_basetype_##_FormatString_string; \
\
ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_##_basetype_; \
void *ZlangCreateDirectProperty_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*_basetype_##_direct_prop = NULL ; \
	\
	_basetype_##_direct_prop = (struct ZlangDirectProperty_##_basetype_ *)ZLMALLOC( sizeof(struct ZlangDirectProperty_##_basetype_) ) ; \
	if( _basetype_##_direct_prop == NULL ) \
	{ \
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" ) \
		return NULL; \
	} \
	memset( _basetype_##_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_##_basetype_) ); \
	\
	return (void *)_basetype_##_direct_prop; \
} \

#define ZlangDestroyDirectProperty_(_basetype_) \
ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_##_basetype_; \
void ZlangDestroyDirectProperty_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	\
	ZLFREE( direct_prop ); \
	\
	return; \
} \

#define ZlangImportObject_(_basetype_,_Basetype_) \
ZlangImportObjectFunction ZlangImportObject_##_basetype_; \
struct ZlangObject *ZlangImportObject_##_basetype_( struct ZlangRuntime *rt ) \
{ \
	struct ZlangObject	*obj = NULL ; \
	struct ZlangFunction	*func = NULL ; \
	int			nret = 0 ; \
	\
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_##_basetype_ , & direct_funcs_##_basetype_ , sizeof(struct ZlangDirectFunctions) , NULL ) ; \
	if( nret ) \
	{ \
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" ) \
		return NULL; \
	} \
	\
	/* _basetype_.FormatString(...) */ \
	func = AddFunctionAndParametersInObject( rt , obj , "FormatString" , "FormatString(string)" , ZlangInvokeFunction_##_basetype_##_FormatString_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , NULL ) ; \
	if( func == NULL ) \
		return NULL; \
	\
	/* _basetype_.IsBetween(_,_) */ \
	func = AddFunctionAndParametersInObject( rt , obj , "IsBetween" , "IsBetween("#_basetype_","#_basetype_")" , ZlangInvokeFunction_IsBetween_##_basetype_##_##_basetype_ , ZLANG_OBJECT_bool , ZLANG_OBJECT_##_basetype_,NULL , ZLANG_OBJECT_##_basetype_,NULL , NULL ) ; \
	if( func == NULL ) \
		return NULL; \
	\
	SetRuntimeFunction_##_basetype_##_Set##_Basetype_##Value( rt , _basetype_##_Set##_Basetype_##Value ); \
        SetRuntimeFunction_##_basetype_##_Get##_Basetype_##Value( rt , _basetype_##_Get##_Basetype_##Value ); \
	\
	return obj ; \
} \

#define ZlangFromCharPtr_(_basetype_) \
ZlangFromCharPtrFunction ZlangFromCharPtr_##_basetype_; \
int ZlangFromCharPtr_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , char *value_ptr , int32_t value_len ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	char					buf[200+1] ; \
	char					*p = NULL ; \
	int					n ; \
	\
	if( value_len < sizeof(buf) ) \
	{ \
		memcpy( buf , value_ptr , value_len ); \
		buf[value_len] = '\0' ; \
	} \
	else \
	{ \
		memcpy( buf , value_ptr , sizeof(buf)-1 ); \
		buf[sizeof(buf)-1] = '\0' ; \
	} \
	\
	if( buf[0] == '0' ) \
	{ \
		if( buf[1] == 'x' ) \
		{ \
			direct_prop->value = 0 ; \
			p = buf + 2 ; \
			while( *p ) \
			{ \
				if( '0' <= (*p) && (*p) <= '9' ) \
				{ \
					n = (*p) - '0' ; \
				} \
				else if( 'a' <= (*p) && (*p) <= 'f' ) \
				{ \
					n = (*p) - 'a' + 10 ; \
				} \
				else if( 'A' <= (*p) && (*p) <= 'F' ) \
				{ \
					n = (*p) - 'A' + 10 ; \
				} \
				else \
				{ \
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LITERAL_INVALID , "literal[%s] invalid " , buf ) \
					return ZLANG_ERROR_LITERAL_INVALID; \
				} \
				\
				direct_prop->value = direct_prop->value * 16 + n ; \
				p++; \
			} \
		} \
		else if( buf[1] == 'o' ) \
		{ \
			direct_prop->value = 0 ; \
			p = buf + 2 ; \
			while( *p ) \
			{ \
				if( '0' <= (*p) && (*p) <= '7' ) \
				{ \
					n = (*p) - '0' ; \
				} \
				else \
				{ \
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LITERAL_INVALID , "literal[%s] invalid " , buf ) \
					return ZLANG_ERROR_LITERAL_INVALID; \
				} \
				\
				direct_prop->value = direct_prop->value * 8 + n ; \
				p++; \
			} \
		} \
		else if( buf[1] == 'b' ) \
		{ \
			direct_prop->value = 0 ; \
			p = buf + 2 ; \
			while( *p ) \
			{ \
				if( (*p) == '0' ) \
				{ \
					n = 0 ; \
				} \
				else if( (*p) == '1' ) \
				{ \
					n = 1 ; \
				} \
				else \
				{ \
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LITERAL_INVALID , "literal[%s] invalid " , buf ) \
					return ZLANG_ERROR_LITERAL_INVALID; \
				} \
				\
				direct_prop->value = direct_prop->value * 2 + n ; \
				p++; \
			} \
		} \
		else \
		{ \
			direct_prop->value = ATOX(buf) ; \
		} \
	} \
	else \
	{ \
		direct_prop->value = ATOX(buf) ; \
	} \
	\
	return 0; \
} \

#define ZlangToString_(_basetype_) \
ZlangToStringFunction ZlangToString_##_basetype_; \
int ZlangToString_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **tostr_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	char					buf[200+1] ; \
	int32_t					len ; \
	\
	memset( buf , 0x00 , sizeof(buf) ); \
	if( direct_prop == NULL ) \
		len = snprintf( buf , sizeof(buf)-1 , "%s" , "(null)" ) ; \
	else \
	{ \
		len = snprintf( buf , sizeof(buf)-1 , FORMAT , direct_prop->value ) ; \
	} \
	CallRuntimeFunction_string_SetStringValue( rt , (*tostr_obj) , buf , len ) ; \
	\
	return 0; \
} \

#define ZlangFromDataPtr_(_basetype_,_ctype_) \
ZlangFromDataPtrFunction ZlangFromDataPtr_##_basetype_; \
int ZlangFromDataPtr_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , void *value_ptr , int32_t value_len ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	\
	if( value_ptr ) \
	{ \
		direct_prop->value = *((_ctype_*)value_ptr) ; \
	} \
	\
	return 0; \
} \

#define ZlangGetDataPtr_(_basetype_) \
ZlangGetDataPtrFunction ZlangGetDataPtr_##_basetype_; \
int ZlangGetDataPtr_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , void **value_ptr , int32_t *value_len ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	\
	if( value_ptr ) \
	{ \
		(*value_ptr) = & (direct_prop->value) ; \
	} \
	\
	if( value_len ) \
	{ \
		(*value_len) = sizeof(direct_prop->value) ; \
	} \
	\
	return 0; \
} \

#define basetype_SetBasetypeValue(_basetype_,_Basetype_,_ctype_) \
ZlangDirectFunction_##_basetype_##_Set##_Basetype_##Value _basetype_##_Set##_Basetype_##Value; \
int _basetype_##_Set##_Basetype_##Value( struct ZlangRuntime *rt , struct ZlangObject *obj , _ctype_ value ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	\
	direct_prop->value = value ; \
	\
	return 0; \
} \

#define basetype_GetBasetypeValue(_basetype_,_Basetype_,_ctype_) \
ZlangDirectFunction_##_basetype_##_Get##_Basetype_##Value _basetype_##_Get##_Basetype_##Value; \
int _basetype_##_Get##_Basetype_##Value( struct ZlangRuntime *rt , struct ZlangObject *obj , _ctype_ *value ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*direct_prop = GetObjectDirectProperty(obj) ; \
	\
	(*value) = direct_prop->value ; \
	\
	return 0; \
} \

#define ZlangOperator_PLUS_(_basetype_,_Basetype_) \
ZlangOperatorFunction ZlangOperator_##_basetype_##_PLUS_##_basetype_; \
int ZlangOperator_##_basetype_##_PLUS_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject **out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(*out_obj) ; \
	out->value = in1->value + in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]+["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangOperator_MINUS_(_basetype_,_Basetype_) \
ZlangOperatorFunction ZlangOperator_##_basetype_##_MINUS_##_basetype_; \
int ZlangOperator_##_basetype_##_MINUS_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject **out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(*out_obj) ; \
	out->value = in1->value - in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]-["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangOperator_MUL_(_basetype_,_Basetype_) \
ZlangOperatorFunction ZlangOperator_##_basetype_##_MUL_##_basetype_; \
int ZlangOperator_##_basetype_##_MUL_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject **out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(*out_obj) ; \
	out->value = in1->value * in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]*["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangOperator_DIV_(_basetype_,_Basetype_) \
ZlangOperatorFunction ZlangOperator_##_basetype_##_DIV_##_basetype_; \
int ZlangOperator_##_basetype_##_DIV_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject **out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	if( in2->value == ZERO ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "*** FATAL : division by zero" ) \
		return ZLANG_ERROR_DIVISION_BY_ZERO; \
	} \
	\
	out = GetObjectDirectProperty(*out_obj) ; \
	out->value = in1->value / in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]/["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangUnaryOperator_NEGATIVE_(_basetype_) \
ZlangUnaryOperatorFunction ZlangUnaryOperator_NEGATIVE_##_basetype_; \
int ZlangUnaryOperator_NEGATIVE_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_out_obj1 ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in_out = GetObjectDirectProperty(in_out_obj1) ; \
	\
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "-["FORMAT"]=>["FORMAT"]" , in_out->value , -in_out->value ) \
	in_out->value = 0-in_out->value ; \
	\
	return 0; \
} \

#define ZlangUnaryOperator_NOT_(_basetype_,_ctype_) \
ZlangUnaryOperatorFunction ZlangUnaryOperator_NOT_##_basetype_; \
int ZlangUnaryOperator_NOT_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_out_obj1 ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in_out = GetObjectDirectProperty(in_out_obj1) ; \
	\
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "!["FORMAT"]=>["FORMAT"]" , in_out->value , (_ctype_) ! (in_out->value) ) \
	in_out->value = ! (in_out->value) ; \
	\
	return 0; \
} \

#define ZlangUnaryOperator_BIT_REVERSE_(_basetype_,_ctype_) \
ZlangUnaryOperatorFunction ZlangUnaryOperator_BIT_REVERSE_##_basetype_; \
int ZlangUnaryOperator_BIT_REVERSE_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_out_obj1 ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in_out = GetObjectDirectProperty(in_out_obj1) ; \
	\
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "~["FORMAT"]=>["FORMAT"]" , in_out->value , (_ctype_) ~ (in_out->value) ) \
	in_out->value = ~ (in_out->value) ; \
	\
	return 0; \
} \

#define ZlangUnaryOperator_PLUS_PLUS_(_basetype_) \
ZlangUnaryOperatorFunction ZlangUnaryOperator_PLUS_PLUS_##_basetype_; \
int ZlangUnaryOperator_PLUS_PLUS_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_out_obj1 ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in_out = GetObjectDirectProperty(in_out_obj1) ; \
	\
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "++["FORMAT"]=>["FORMAT"]" , in_out->value , in_out->value+1 ) \
	in_out->value++; \
	\
	return 0; \
} \

#define ZlangUnaryOperator_MINUS_MINUS_(_basetype_) \
ZlangUnaryOperatorFunction ZlangUnaryOperator_MINUS_MINUS_##_basetype_; \
int ZlangUnaryOperator_MINUS_MINUS_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_out_obj1 ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in_out = GetObjectDirectProperty(in_out_obj1) ; \
	\
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "--["FORMAT"]=>["FORMAT"]" , in_out->value , in_out->value-1 ) \
	in_out->value--; \
	\
	return 0; \
} \

#define ZlangCompare_EGUAL_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_EGUAL_##_basetype_; \
int ZlangCompare_##_basetype_##_EGUAL_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value == in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]==["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]==["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangCompare_NOTEGUAL_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_NOTEGUAL_##_basetype_; \
int ZlangCompare_##_basetype_##_NOTEGUAL_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value != in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]!=["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]!=["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangCompare_LT_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_LT_##_basetype_; \
int ZlangCompare_##_basetype_##_LT_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value < in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]<["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]<["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangCompare_LE_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_LE_##_basetype_; \
int ZlangCompare_##_basetype_##_LE_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value <= in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]<=["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]<=["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangCompare_GT_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_GT_##_basetype_; \
int ZlangCompare_##_basetype_##_GT_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value > in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]>["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]>["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangCompare_GE_(_basetype_) \
ZlangCompareFunction ZlangCompare_##_basetype_##_GE_##_basetype_; \
int ZlangCompare_##_basetype_##_GE_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	\
	if( in1->value >= in2->value ) \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]>=["FORMAT"]=>[true]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE ); \
	} \
	else \
	{ \
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]>=["FORMAT"]=>[false]" , in1->value , in2->value ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE ); \
	} \
	\
	return 0; \
} \

#define ZlangBit_AND_(_basetype_) \
ZlangBitFunction ZlangBit_##_basetype_##_AND_##_basetype_; \
int ZlangBit_##_basetype_##_AND_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(out_obj) ; \
	out->value = in1->value & in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]&["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangBit_XOR_(_basetype_) \
ZlangBitFunction ZlangBit_##_basetype_##_XOR_##_basetype_; \
int ZlangBit_##_basetype_##_XOR_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(out_obj) ; \
	out->value = in1->value ^ in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]^["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangBit_OR_(_basetype_) \
ZlangBitFunction ZlangBit_##_basetype_##_OR_##_basetype_; \
int ZlangBit_##_basetype_##_OR_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*in2 = GetObjectDirectProperty(in_obj2) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	\
	out = GetObjectDirectProperty(out_obj) ; \
	out->value = in1->value | in2->value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]|["FORMAT"]=>["FORMAT"]" , in1->value , in2->value , out->value ) \
	\
	return 0; \
} \

#define ZlangBit_MOVELEFT_(_basetype_) \
ZlangBitFunction ZlangBit_##_basetype_##_MOVELEFT_int; \
int ZlangBit_##_basetype_##_MOVELEFT_int( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	int32_t					in2_value ; \
	\
	CallRuntimeFunction_int_GetIntValue( rt , in_obj2 , & in2_value ); \
	\
	out = GetObjectDirectProperty(out_obj) ; \
	out->value = in1->value << in2_value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]<<[%d]=>["FORMAT"]" , in1->value , in2_value , out->value ) \
	\
	return 0; \
} \

#define ZlangBit_MOVERIGHT_(_basetype_) \
ZlangBitFunction ZlangBit_##_basetype_##_MOVERIGHT_int; \
int ZlangBit_##_basetype_##_MOVERIGHT_int( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*in1 = GetObjectDirectProperty(in_obj1) ; \
	struct ZlangDirectProperty_##_basetype_	*out = NULL ; \
	int32_t					in2_value ; \
	\
	CallRuntimeFunction_int_GetIntValue( rt , in_obj2 , & in2_value ); \
	\
	out = GetObjectDirectProperty(out_obj) ; \
	out->value = in1->value >> in2_value ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "["FORMAT"]>>[%d]=>["FORMAT"]" , in1->value , in2_value , out->value ) \
	\
	return 0; \
} \

#define ZlangSummarizeDirectPropertySize_(_basetype_) \
ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_##_basetype_; \
void ZlangSummarizeDirectPropertySize_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size ) \
{ \
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_##_basetype_) ) \
	return; \
} \

#define ZlangCompare_FormatString_string_(_basetype_) \
ZlangInvokeFunction ZlangInvokeFunction_##_basetype_##_FormatString_string; \
int ZlangInvokeFunction_##_basetype_##_FormatString_string( struct ZlangRuntime *rt , struct ZlangObject *obj ) \
{ \
	struct ZlangDirectProperty_##_basetype_	*obj_direct_prop = GetObjectDirectProperty(obj) ; \
	struct ZlangObject			*in = GetInputParameterInLocalObjectStack(rt,1) ; \
	struct ZlangObject			*out = GetOutputParameterInLocalObjectStack(rt,1) ; \
	char					*format = NULL ; \
	int					fill_len ; \
	char					*buf = NULL ; \
	\
	int					nret = 0 ; \
	\
	GetDataPtr( rt , in , (void**) & format , NULL ); \
	\
	fill_len = snprintf( NULL , 0 , format , obj_direct_prop->value ) ; \
	buf = ZLMALLOC( fill_len+1 ) ; \
	if( buf == NULL ) \
	{ \
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for " #_basetype_ " str buf" ) \
		return ZLANG_ERROR_ALLOC; \
	} \
	sprintf( buf , format , obj_direct_prop->value ); \
	\
	nret = FromCharPtr( rt , out , buf , fill_len ) ; \
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" value\""FORMAT"\" -> formatting\"%s\"" , format , obj_direct_prop->value , buf ) \
	ZLFREE( buf ); \
	if( nret ) \
		return nret; \
	\
	return 0; \
} \

#define ZlangCompare_IsBetween_v_v(_basetype_,_Basetype_,_ctype_) \
ZlangInvokeFunction ZlangInvokeFunction_IsBetween_##_basetype_##_##_basetype_; \
int ZlangInvokeFunction_IsBetween_##_basetype_##_##_basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj ) \
{ \
	struct ZlangObject			*in1_obj = GetInputParameterInLocalObjectStack(rt,1) ; \
	struct ZlangObject			*in2_obj = GetInputParameterInLocalObjectStack(rt,2) ; \
	struct ZlangObject			*out1_obj = GetOutputParameterInLocalObjectStack(rt,1) ; \
	_ctype_					in ; \
	_ctype_					in1 ; \
	_ctype_					in2 ; \
	\
	CallRuntimeFunction_##_basetype_##_Get##_Basetype_##Value( rt , obj , & in ); \
	CallRuntimeFunction_##_basetype_##_Get##_Basetype_##Value( rt , in1_obj , & in1 ); \
	CallRuntimeFunction_##_basetype_##_Get##_Basetype_##Value( rt , in2_obj , & in2 ); \
	\
	if( in1 <= in && in <= in2 ) \
		CallRuntimeFunction_bool_SetBoolValue( rt , out1_obj , TRUE ); \
	else \
		CallRuntimeFunction_bool_SetBoolValue( rt , out1_obj , FALSE ); \
	\
	return 0; \
} \

